# 1. program -> compUnit    程序由多个语句单元组成
# 2. compUnit -> decl compUnit  语句单元可以是声明
# 3. compUnit -> funcDef compUnit   语句单元可以是函数定义
# 4. compUnit -> $  语句单元可以是空
# 5. decl -> constDecl  常量声明
# 6. decl -> varDecl    变量声明
# 7. constDecl -> const bType constDef argConst ;   形如 const int a = 123 , b = 456 ...
# 8. argConst -> , constDef argConst
# 9. argConst -> $
# 10. constDef -> Ident = constInitVal  Ident为基本元素，变量名
# 11. constInitVal -> constExp  常量表达式
# 12. varDecl -> bType varDef argVarDecl ;  与7一样，没有const，多 int a;,即不给值
# 13. argVarDecl -> , varDef argVarDecl
# 14. argVarDecl -> $
# 15. varDef -> Ident argVarDef
# 16. argVarDef -> = initVal
# 17. argVarDef -> $
# 18. initVal -> exp
# 19. bType -> int
# 20. bType -> float
# 21. bType -> char
# 22. funcDef -> funcType Ident ( funcFParams ) block   返回值类型+名字+参数列表+函数体
# 23. funcType -> void
# 24. funcFParams -> funcFParam argFunctionF    int a , int b ...（可以为空）
# 25. funcFParams -> $
# 26. argFunctionF -> , funcFParam argFunctionF
# 27. argFunctionF -> $
# 28. funcFParam -> bType Ident
# 29. block -> { blockItem }    函数体加括号
# 30. blockItem -> decl blockItem   函数体中有多个声明
# 31. blockItem -> stmt blockItem   其他
# 32. blockItem -> $
# 33. stmt -> exp ; 表达式
# 34. stmt -> ; 
# 35. stmt -> block
# 36. stmt -> return argExp ;   返回
# 37. argExp -> $
# 38. argExp -> exp
# 39. exp -> assignExp
# 40. lVal -> Ident
# 41. primaryExp -> ( exp )
# 42. primaryExp -> number
# 43. number -> INT
# 44. unaryOp -> +
# 45. unaryOp -> -
# 46. unaryOp -> !
# 47. unaryExp -> unaryOp unaryExp
# 48. unaryExp -> Ident callFunc
# 49. callFunc -> ( funcRParams )
# 50. callFunc -> $
# 51. unaryExp -> primaryExp
# 52. funcRParams -> funcRParam argFunctionR
# 53. funcRParams -> $
# 54. argFunctionR -> , funcRParam argFunctionR
# 55. argFunctionR -> $
# 56. funcRParam -> exp
# 57. mulExp -> unaryExp mulExpAtom
# 58. mulExpAtom -> * unaryExp mulExpAtom
# 59. mulExpAtom -> / unaryExp mulExpAtom
# 60. mulExpAtom -> % unaryExp mulExpAtom
# 61. mulExpAtom -> $
# 62. addExp -> mulExp addExpAtom
# 63. addExpAtom -> + mulExp addExpAtom
# 64. addExpAtom -> - mulExp addExpAtom
# 65. addExpAtom -> $
# 66. relExp -> addExp relExpAtom
# 67. relExpAtom -> < addExp relExpAtom
# 68. relExpAtom -> > addExp relExpAtom
# 69. relExpAtom -> <= addExp relExpAtom
# 70. relExpAtom -> >= addExp relExpAtom
# 71. relExpAtom -> $
# 72. eqExp -> relExp eqExpAtom
# 73. eqExpAtom -> == relExp eqExpAtom
# 74. eqExpAtom -> != relExp eqExpAtom
# 75. eqExpAtom -> $
# 76. assignExp -> eqExp assignExpAtom
# 77. assignExpAtom -> = eqExp assignExpAtom
# 78. assignExpAtom -> $
# 79. constExp -> assignExp
# 接下来是针对struct和union的扩展：
# compUnit -> aggregateDef compUnit    //语句单元可以是聚合，即struct和union
# keyword -> struct    //定义struct关键字
# keyword -> union    //定义union关键字
# aggregateDef -> keyword Ident { aggregateBlockElem } aggregateVarDecl1 ;    //定义聚合类型的结构为：关键字+聚合类型名+{成员}+变量名
# aggregateBlockElem -> $    //可以为空
# decl -> aggregateDecl    //聚合类型的变量声明
# aggregateDecl -> keyword Ident aggregateVarDecl2 ;    //声明结构为：关键字+聚合类型名+变量名+;
# aggregateVarDecl2 -> Ident argAggregateVar    //可以一次性声明一个或多个聚合类型变量
# aggregateBlockElem -> decl aggregateBlockElem    //成员中可以有成员变量
# bType -> keyword    //使函数的参数支持聚合类型
# aggregateBlockElem -> funcDef aggregateBlockElem    //成员中可以有成员函数
# aggregateVarDecl1 -> $    //可以不伴随聚合类型声明变量
# aggregateVarDecl1 -> Ident argAggregateVar
# argAggregateVar -> , Ident argAggregateVar
# argAggregateVar -> $  //可以伴随聚合类型声明一个或多个变量
# 以下是有空就做没空拉到的待定项：
# 缺一个 struct Point p1 = {10, 20}; 的声明方式
# 缺struct Point p1;  // 声明一个结构体变量 p1
# p1.x = 10;
# p1.y = 20;
# 接下来是针对switch的扩展：
# blockItem -> switchDef blockItem    //在函数体中可以有switch语句
# switchDef -> switch ( exp ) { branch }    //定义switch语句的结构为：switch关键字+(+表达式+)+{+分支+}
# switchDef -> switch ( exp ) ;    //switch语句的结构也可以为：switch关键字+(+表达式+)+;
# branch -> caseBranch branch     //分支有case分支（多个）
# branch -> defaultBranch    //分支有default分支（也可以没有）
# branch -> $    //可以为空
# caseBranch -> case exp : body    //定义case分支的结构为：case关键字+表达式+:+内容
# body -> { blockItem breakItem }    //body其实和block是相似的，只不过需要在大括号内加上break
# breakItem -> break ;    //⽀持break语句
# breakItem -> $    //分支中也可以没有break
# defaultBranch -> default : body    //定义default分支的结构为：default关键字+:+内容